前面聲音與影像的基本原理都學習完後,咱們接下來要來實作一些東西。
在筆者的30-09之別人要如何聽到我的聲音呢 ?有提到三種影音的傳遞方式,分別為:
接下來我們將來實作方法 2 的選項,而這東西事實上就是點播網站的應用,像 KKTV、楓林網就是這種類型的應用,本篇文章將會說明:
如何建立的像 KKTV 一樣的點播功能呢 (可以動就好版) ?
先說好,如果真的要建立像 KKTV 一樣的可營運的應用,還需要做不少架構的調整,這裡就是只是學習如何做出可以動的點播網站,也就是可以看片 (不是全部下載完才可以看)。
本篇將分為以下幾個章節:
基本上點播的架構,最基本(不管流量或 CDN 這些鬼)的樣貌會如下:
然後基本上可以選擇的協議有RTMP
、HLS
、HTTP-FLV
、MPEG-DASH
。
那這裡問個問題 ?
基本上我覺得是要看你的用戶端的裝置取向,基本上以現在的狀態選擇 HLS 與 MPEG-DASH 在點播類的應用,應該是最安穩的,最主要我覺得有以下三個原因:
這兩個協議可以去參考筆者的以下兩篇文章。
30-17之 MPEG-DASH 傳輸協議
30-15之 HLS 傳輸協議
接下來咱們就先以 HLS 為主,來開始來進行實作 ( Dash 的建立實際上也差不多 )。
首先第一部,我們要先建立一個 Media Server,它的主要功能有以下兩個:
Media Server 現在的選擇事實上很多,像以 nodejs 來說可以使用下面連結的這個,非常的簡單,而 nginx 它也有提供一些 media server 的套件。
nodejs-media-server
nginx-rtmp-module
nodejs-hls-server
接下來我們簡單的以 nodejs-hls-server 這個套件來實作個 Media Server。
這個 Media Server 有兩件事情要處理。
首先咱們先來看看 Server 的部份,基本上程式碼很簡單,就像它套件裡面使用的,建立一個 Http Server 然後將 HLS 的套件附加到裡面。
// index.js
const HLSServer = require('hls-server')
const http = require('http')
const server = http.createServer()
const hls = new HLSServer(server, {
path: '/streams', // Base URI to output HLS streams
dir: 'source-m3u8' // Directory that input files are stored
})
server.listen(8000)
然後這裡還要做一件事情,那就是將 .mp4 影片檔轉換成 .m3u8 檔,這裡我們就需要使用到前一篇文章說的 ffmpeg 的神器,基本上程式碼如下,這裡我將套件裡的範例改成 async/await 的版本。
然後下面這段程式碼,就會將輸入的 .mp4 檔轉換成每 10 秒一段的 .ts 檔,然後最後在產生出 .m3u8 檔到你指定的位置。
const ffmpeg = require('fluent-ffmpeg')
module.exports = {
convertToHls: async (file) => {
return new Promise((resolve) => {
ffmpeg(file, { timeout: 432000 }).addOptions([
'-profile:v baseline', // for H264 video codec
'-level 3.0',
'-s 640x360', // 640px width, 360px height
'-start_number 0', // start the first .ts segment at index 0
'-hls_time 10', // 10 second segment duration
'-hls_list_size 0', // Maxmimum number of playlist entries)
'-f hls' // HLS format
]).output(`./source-m3u8/output.m3u8`).on('end', resolve).run()
});
}
}
上面這段要在 Server 啟動前先完成,使用範例如下:
// conver.js
const ffmpegHelper = require('./ffmpeg-helper’);
(async () => {
await ffmpegHelper.convertToHls(‘./source-mp4/input.mp4’);
})();
最要在執行以下兩段程式碼,然後就可以使用了。
node conver.js // 轉換成 .m3u8 檔
node index.js //啟動 server
然後到了這裡 Server 端,就準備才不多了。接下來就進入到用戶端。
對了如果你在完成 server 以後,想要先測試一下你轉的 .m3u8 檔可不可以看,可以使用 ffplay 來測看看,執行完有看到影片就代表 ok !
ffplay http://127.0.0.1:8000/streams/output.m3u8
接下來咱們來建立一個可以在網頁上。
基本上要做的事情有以下幾件:
<html>
<head><title>Test</title></head>
<body>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video controls id="video"></video>
<input type="text" />
<button id="load">Load</button>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
document.querySelector("#load").addEventListener("click", function () {
hls.loadSource(document.querySelector("input").value);
})
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.addEventListener('canplay',function() {
video.play();
});
document.querySelector("#load").addEventListener("click", function () {
video.src = document.querySelector("input").value;
})
}
</script>
</body>
</html>
執行結果如下圖。
本篇文章中,咱們學習到如何建立最簡單可以動的點播功能,基本上重點就是三個功能。
接下來下一篇文章咱們將要來學習如何建立一個直播功能
。
請問我想用node.js把mp4檔案轉成hls的檔案,但複製您的node.js程式執行後,無錯誤訊息,但也沒有hls相關的檔案產生,但相同的參數,直接用ffmpeg轉檔確可成功,是我哪裡沒設定好嗎?
呃不好意思…… 下面這一段有點問題 ~ 抱歉 ~
// conver.js
const ffmpegHelper = require('./ffmpeg-helper’);
(async () => {
await ffmpegHelper.convertToHls(‘./source-mp4/input.mp4’);
});
改成如下
// conver.js
const ffmpegHelper = require('./ffmpeg-helper’);
(async () => {
await ffmpegHelper.convertToHls(‘./source-mp4/input.mp4’);
})();
樣應該會有看到產生的 hls 了。